<template>
  <Page title="作业" :on-page-back="onPageBack" :bgColor="'#EAEAEAFF'">
    <template #navBarCustom>
      <NewBar
        title="作业"
        :tabs="subjects.list"
        :usedSubject="subjects.usedSubject"
        :moreSubject="subjects.moreSubject"
        :active="subjects.active"
        @change="subjects.onChange($event)"
      >
        <template #rightBtn>
          <!-- <div class="item flex items-center"  @click="goToRecords">
              <img class="icon mt-2px mr-6px" src="static/icons/record.png" mode="" />
              <span class="name text-white">练习记录</span>
            </div> -->
        </template>
      </NewBar>
    </template>
    <template #content>
      <div class="w-full h-full px-20px box-border flex flex-col">
        <!-- 学科列表 -->

        <!-- 作业列表 -->
        <scroll-view
          ref="scroll"
          class="flex-1 overflow-scroll"
          :refresher-enabled="true"
          :refresher-loader-offset-y="-16"
          @scrolltolower="homeworks.getList(subjects.active)"
          @refresh="homeworks.refresh($event)"
        >
          <homework-list :list="homeworks.list" @todo="homeworks.todo($event)" />
          <load-more
            cssStyle="padding-top:0.14rem"
            :loading="homeworks.loading"
            :has-more="homeworks.hasMore"
            @click="homeworks.getList(subjects.active)"
          />
        </scroll-view>
      </div>
    </template>
  </Page>
</template>

<script>
import Page from '@/components/page/newPage'
import SubjectTabs from '@/components/subject/tabs'
import NewBar from '@/components/subject/tabs/newTabs'
import ScrollView from '@/components/scroll-view'
import HomeworkList from './components/homework-list'
import LoadMore from '@/components/load-more'
import {
  getStudentExamSubjectApi,
  getStudentExamListApi,
  getStudentExamApi,
  getQuestionsApi,
  upExamCompleteApi,
  updateExamStudentEndtimeApi
} from '@/api/homework'
import { mapState, mapGetters, mapActions } from 'vuex'
import { debounce } from '@/utils'
import { generateStudentAnswer } from '@/utils/question'
import { MODULE_ID } from '@/store/modules/module-use'

export default {
  components: {
    Page,
    ScrollView,
    SubjectTabs,
    HomeworkList,
    LoadMore,
    NewBar
  },
  beforeRouteEnter(to, from, next) {
    next((vm) => {
      console.log(vm)
      if (from.params.completed) {
        const subjectId = vm.subjects.active
        vm.homeworks.reset()
        vm.homeworks.getList(subjectId)
      }
    })
  },
  data() {
    return {
      loading: null,
      examIds: {},
      storageExamIds: {},
      lastHomeWorkId: '',
      // 学科栏目
      subjects: {
        vm: this._self,
        active: '',
        list: [],
        usedSubject: [],
        moreSubject: [],
        getList: async function (callback) {
          const { data = [] } = await getStudentExamSubjectApi()
          const subjects = await this.vm.getDictByType('subject')
          this.usedSubject = subjects.filter((item) => {
            return ['1', '2', '3', '4', '5'].includes(item.value)
          })
          this.usedSubject.unshift({
            value: '',
            label: '全部'
          })
          this.moreSubject = subjects.filter((item) => {
            return !['1', '2', '3', '4', '5'].includes(item.value)
          })
          const list = []
          data.forEach((i) => {
            const subject = subjects.find((s) => s.value == i)
            list.push({
              dictType: 'subject',
              label: subject.label,
              status: 0,
              value: subject.value
            })
          })
          // 如果没有开通的科目，弹出弹窗
          if (list.length === 0) {
            this.vm.$popup.show({
              type: 'alert',
              success: (popup) => {
                popup.$on('confirm', () => {
                  this.vm.$popup.hide('alert')
                  this.vm.$router.back()
                })
                popup.setData({
                  content: '没有已开通的科目'
                })
              }
            })
            return
          }

          list.unshift({
            dictType: 'subject',
            label: '全部',
            status: 0,
            value: ''
          })
          this.list = list.map((item) => {
            const { value: subjectId } = item
            subjectId &&
              this.vm.$storage.homework.getExamIdsItem(subjectId).then(({ success, data }) => {
                success && (this.vm.storageExamIds[subjectId] = data)
              })
            return item
          })
          callback('')
        },
        onChange: debounce(function (subjectId) {
          // 上传模块使用时间
          this.vm.$store.state.moduleUse.currentModuleUse.submit()
          // 重置
          this.vm.$store.state.moduleUse.currentModuleUse.onSubjectChange(subjectId)

          this.active = subjectId
          this.vm.homeworks.reset()
          this.vm.homeworks.getList(subjectId)
        }, 300)
      },
      homeworks: {
        vm: this._self,
        pageNo: 1,
        pageSize: 12,
        loading: true,
        hasMore: true,
        list: [],
        getList: async function (subjectId) {
          if (this.loading) return

          this.loading = true
          const homeworks = this.list

          let params = {
            pageNo: this.pageNo,
            pageSize: this.pageSize,
            examIs: 0
          }

          if (subjectId) params['subject'] = subjectId

          const {
            data: { list }
          } = await getStudentExamListApi(params)

          if (list.length < this.pageSize) {
            this.hasMore = false
          }

          if (list.length > 0) {
            if (this.pageNo === 1 && !subjectId) {
              this.vm.lastHomeWorkId = list[0].id
            }

            const { examIds } = this.vm

            homeworks.push(
              ...list.map((item) => {
                const currentSubjectId = this.vm.subjects.active
                const { subject: subjectId, id: examId } = item
                const storage_exam_ids_item = this.vm.storageExamIds[currentSubjectId]

                // 标记是否已读
                if (!currentSubjectId) {
                  item['unread'] = 1
                  for (let subjectId in this.vm.storageExamIds) {
                    if (this.vm.storageExamIds[subjectId].find((id) => id === examId)) {
                      item['unread'] = 0
                      break
                    }
                  }
                } else if (
                  storage_exam_ids_item &&
                  storage_exam_ids_item.find((id) => id === examId)
                ) {
                  item['unread'] = 0
                } else {
                  item['unread'] = 1
                }

                // 缓存id
                if (examIds[subjectId]) {
                  const exam_ids = examIds[subjectId]
                  examIds[subjectId] = Array.from(new Set(exam_ids.concat(examId)))
                } else {
                  examIds[subjectId] = [examId]
                }

                return item
              })
            )
            this.pageNo++
          }

          this.loading = false
        },
        refresh: async function (done = () => {}) {
          const currentSubjectId = this.vm.subjects.active
          const params = {
            pageNo: (this.pageNo = 1),
            pageSize: this.pageSize,
            examIs: 0,
            subject: currentSubjectId ? currentSubjectId : undefined
          }

          const {
            data: { list }
          } = await getStudentExamListApi(params)

          this.list.length = 0
          this.list.push(
            ...list.map((item) => {
              const { examIds } = this.vm
              const { subject: subjectId, id: examId } = item
              const storage_exam_ids_item = this.vm.storageExamIds[currentSubjectId]

              // 标记是否已读
              if (!currentSubjectId) {
                item['unread'] = 1
                for (let subjectId in this.vm.storageExamIds) {
                  if (this.vm.storageExamIds[subjectId].find((id) => id === examId)) {
                    item['unread'] = 0
                    break
                  }
                }
              } else if (
                storage_exam_ids_item &&
                storage_exam_ids_item.find((id) => id === examId)
              ) {
                item['unread'] = 0
              } else {
                item['unread'] = 1
              }

              // 缓存id
              if (examIds[subjectId]) {
                const exam_ids = examIds[subjectId]
                examIds[subjectId] = Array.from(new Set(exam_ids.concat(examId)))
              } else {
                examIds[subjectId] = [examId]
              }

              return item
            })
          )
          this.pageNo++

          done()
        },
        reset: function () {
          this.pageNo = 1
          this.pageSize = 12
          this.loading = false
          this.hasMore = true
          this.list = []
        },
        todo: async function (item) {
          const { subject: subjectId, examType } = item

          switch (examType) {
            case 4:
              // 非习题作业
              {
                const {
                  id, // 作业id
                  studentStatus = 0, // 作业状态
                  answerTime, // 作答时间(分)
                  answerTimeType // 作答时间类型 1 => 开始时间计 2 => 进入作答计
                } = item
                const isSubmited = studentStatus !== 0 // 是否已提交作业

                // 开始作答
                const start = async () => {
                  // 加载动画
                  const loading = this.vm.$loading({
                    lock: true,
                    text: '加载中...',
                    spinner: 'el-icon-loading',
                    background: 'rgba(0, 0, 0, 0.5)'
                  })
                  // 一分钟内加载不成功关闭loading弹窗
                  const timer = setTimeout(() => {
                    loading.close()
                  }, 60000)

                  // 查看是否存在缓存
                  const { success, data } = await this.vm.$storage.homework.getCacheItem(id)
                  if (!isSubmited && success) {
                    const {
                      record: { beginTime, endTime }
                    } = data
                    const nowTime = new Date().getTime()

                    // 判断是否未到开始时间
                    if (beginTime) {
                      const beginTimestamp = new Date(beginTime).getTime()

                      if (nowTime < beginTimestamp) {
                        clearTimeout(timer)
                        loading.close()
                        this.vm.$message.error('未到作答时间')
                        return
                      }
                    }

                    // 判断是否已超过结束时间
                    if (endTime) {
                      const endTimestamp = new Date(endTime).getTime()

                      if (nowTime > endTimestamp) {
                        clearTimeout(timer)
                        loading.close()
                        this.vm.$message.error('已超过作答时间')
                        return
                      }
                    }

                    this.vm.$store.commit('setCurrentHomework', data)
                  } else {
                    let { beginTime, endTime } = item

                    // 判断作答时间
                    if (!isSubmited) {
                      // 如果从进入作答开始计时，生成结束时间
                      if (answerTime && answerTimeType === 2) {
                        const nowTime = new Date().getTime()
                        const finalEndTime = this.vm.$utils.parseTime(
                          (nowTime + '').length === 13
                            ? nowTime + answerTime * 60 * 1000
                            : nowTime * 1000 + answerTime * 60 * 1000,
                          '{y}-{m}-{d} {h}:{i}:{s}'
                        )
                        await updateExamStudentEndtimeApi({
                          examId: id,
                          studentId: this.vm.studentId,
                          seconds: answerTime * 60
                        })
                        endTime = finalEndTime
                      }

                      const nowTime = new Date().getTime()

                      // 判断是否未到开始时间
                      if (beginTime) {
                        const beginTimestamp = new Date(beginTime).getTime()

                        if (nowTime < beginTimestamp) {
                          clearTimeout(timer)
                          loading.close()
                          this.vm.$message.error('未到作答时间')
                          return
                        }
                      }

                      // 判断是否已超过结束时间
                      if (endTime) {
                        const endTimestamp = new Date(endTime).getTime()

                        if (nowTime > endTimestamp) {
                          clearTimeout(timer)
                          loading.close()
                          this.vm.$message.error('已超过作答时间')
                          return
                        }
                      }
                    }

                    // 获取作业详情
                    const { data: record } = await getStudentExamApi({
                      id
                    })

                    const { questionDataUrl } = record
                    record.endTime = endTime

                    if (!questionDataUrl) {
                      this.vm.$message.error('获取作业详情失败')
                      clearTimeout(timer)
                      loading.close()
                      return
                    }

                    const res = await getQuestionsApi(questionDataUrl, { subjectId, examType })

                    const questions = res.map((i, index) => {
                      i['localStudentAnswer'] = {
                        examId: id,
                        questionId: i.questionId,
                        studentId: this.vm.studentId,
                        completeFlag: index === res.length - 1 ? 1 : 0,
                        studentAnswer: '',
                        studentAnswerUrl: '',
                        studentAnswerFiles: [],
                        studentDuration: 0
                      }

                      return i
                    })

                    this.vm.$store.commit('setCurrentHomework', {
                      record,
                      questions,
                      questionIndex: 0
                    })

                    if (!isSubmited) {
                      this.vm.$storage.homework.setCacheItem({
                        id,
                        value: {
                          record,
                          questions,
                          questionIndex: 0
                        }
                      })
                    }
                  }

                  // 关闭加载动画
                  clearTimeout(timer)
                  loading.close()

                  if (!isSubmited) {
                    // 去提交
                    this.vm.$router.push('/pages/homework/todo/task/index')
                  } else {
                    // 查看详情
                    this.vm.$router.push('/pages/homework/detail/task/index')
                  }
                }

                // 弹窗提示
                if (!isSubmited && answerTime && answerTimeType === 2) {
                  this.vm.$popup.show({
                    type: 'confirm',
                    success: (popup) => {
                      popup.$on('cancel', () => {
                        this.vm.$popup.hide('confirm')
                      })
                      popup.$on('confirm', async () => {
                        this.vm.$popup.hide('confirm')
                        start()
                      })
                      popup.setData({
                        content: `当前已限制作答时长，进入作答${answerTime}分钟后，系统将自动提交，确认开始作答？`,
                        confirmText: '确认'
                      })
                    }
                  })
                } else {
                  start()
                }
              }
              break
            default:
              // 习题作业
              {
                const {
                  id, // 作业id
                  studentStatus = 0, // 作业状态
                  answerTime, // 作答时间(分)
                  answerTimeType // 作答时间类型 1 => 开始时间计 2 => 进入作答计
                } = item
                const isSubmited = studentStatus !== 0 // 是否已提交作业

                // 开始作答
                const start = async () => {
                  // 加载动画
                  const loading = this.vm.$loading({
                    lock: true,
                    text: '加载中...',
                    spinner: 'el-icon-loading',
                    background: 'rgba(0, 0, 0, 0.5)'
                  })
                  // 一分钟内加载不成功关闭loading弹窗
                  const timer = setTimeout(() => {
                    loading.close()
                  }, 60000)

                  // 查看是否存在缓存
                  const { success, data } = await this.vm.$storage.homework.getCacheItem(id)
                  if (!isSubmited && success) {
                    const {
                      record: { beginTime, endTime }
                    } = data
                    const nowTime = new Date().getTime()

                    // 判断是否未到开始时间
                    if (beginTime) {
                      const beginTimestamp = new Date(beginTime).getTime()

                      if (nowTime < beginTimestamp) {
                        clearTimeout(timer)
                        loading.close()
                        this.vm.$message.error('未到作答时间')
                        return
                      }
                    }

                    // 判断是否已超过结束时间
                    if (endTime) {
                      const endTimestamp = new Date(endTime).getTime()

                      if (nowTime > endTimestamp) {
                        clearTimeout(timer)
                        loading.close()
                        this.vm.$message.error('已超过作答时间')
                        return
                      }
                    }

                    try {
                      // 获取作业详情
                      const {
                        data: { questionDataUrl }
                      } = await getStudentExamApi({
                        id
                      })

                      const res = await getQuestionsApi(questionDataUrl, { subjectId })

                      const questions = res.map((i, index) => {
                        i['localStudentAnswer'] = {
                          examId: id,
                          questionId: i.questionId,
                          studentId: this.vm.studentId,
                          completeFlag: index === res.length - 1 ? 1 : 0,
                          studentAnswer: i.answerScoreable
                            ? generateStudentAnswer({
                                init: i.questionSplit.answer
                              })
                            : '',
                          studentAnswerUrl: '',
                          studentDuration: 0
                        }
                        // 答题状态 0 => 未答题 1 => 已答题
                        i['localStudentAnswerStatus'] = 0
                        i['extraInfo'] = {
                          xkw: {}, // 学科网
                          english: { stageIndex: 0 } // 英语听说
                        }

                        return i
                      })

                      const { questions: questionsCache } = data

                      if (!(Array.isArray(questionsCache) && Array.isArray(questions))) return

                      questionsCache.forEach((item) => {
                        const { stem, answer, explanation, questionSplit, answerScoreable } =
                          questions.find((q) => item.questionId === q.questionId)

                        // 重置stem
                        item.stem = stem
                        // 重置answer
                        item.answer = answer
                        // 重置explanation
                        item.explanation = explanation
                        // 重置questionSplit
                        item.questionSplit = questionSplit
                        // 重置answerScoreable
                        item.answerScoreable = answerScoreable
                      })
                    } catch (error) {}

                    this.vm.$store.commit('setCurrentHomework', data)
                  } else {
                    let { questionNum = 0, beginTime, endTime } = item

                    if (!isSubmited) {
                      // 如果从进入作答开始计时，生成结束时间
                      if (answerTime && answerTimeType === 2) {
                        const nowTime = new Date().getTime()
                        const finalEndTime = this.vm.$utils.parseTime(
                          (nowTime + '').length === 13
                            ? nowTime + answerTime * 60 * 1000
                            : nowTime * 1000 + answerTime * 60 * 1000,
                          '{y}-{m}-{d} {h}:{i}:{s}'
                        )
                        await updateExamStudentEndtimeApi({
                          examId: id,
                          studentId: this.vm.studentId,
                          seconds: answerTime * 60
                        })
                        endTime = finalEndTime
                      }

                      const nowTime = new Date().getTime()

                      // 判断是否未到开始时间
                      if (beginTime) {
                        const beginTimestamp = new Date(beginTime).getTime()

                        if (nowTime < beginTimestamp) {
                          clearTimeout(timer)
                          loading.close()
                          this.vm.$message.error('未到作答时间')
                          return
                        }
                      }

                      // 判断是否已超过结束时间
                      if (endTime) {
                        const endTimestamp = new Date(endTime).getTime()

                        if (nowTime > endTimestamp) {
                          clearTimeout(timer)
                          loading.close()
                          this.vm.$message.error('已超过作答时间')
                          return
                        }
                      }

                      // 提交普通作业
                      if (!questionNum) {
                        const { data: success } = await upExamCompleteApi({
                          examId: id,
                          studentId: this.vm.studentId
                        })

                        if (success) {
                          item.studentStatus = 20
                          this.vm.$message.success('提交成功')
                        }

                        clearTimeout(timer)
                        loading.close()
                        return
                      }
                    }

                    // 获取作业详情
                    const { data: record } = await getStudentExamApi({
                      id
                    })

                    const { questionDataUrl } = record
                    record.endTime = endTime

                    if (!questionDataUrl) {
                      this.vm.$message.error('获取作业详情失败')
                      clearTimeout(timer)
                      loading.close()
                      return
                    }

                    const res = await getQuestionsApi(questionDataUrl, { subjectId })

                    const questions = res.map((i, index) => {
                      i['localStudentAnswer'] = {
                        examId: id,
                        questionId: i.questionId,
                        studentId: this.vm.studentId,
                        completeFlag: index === res.length - 1 ? 1 : 0,
                        studentAnswer: i.answerScoreable
                          ? generateStudentAnswer({
                              init: i.questionSplit.answer
                            })
                          : '',
                        studentAnswerUrl: '',
                        studentDuration: 0
                      }
                      // 答题状态 0 => 未答题 1 => 已答题
                      i['localStudentAnswerStatus'] = 0
                      i['extraInfo'] = {
                        xkw: {}, // 学科网
                        english: { stageIndex: 0 } // 英语听说
                      }

                      return i
                    })

                    this.vm.$store.commit('setCurrentHomework', {
                      record,
                      questions,
                      questionIndex: 0
                    })

                    if (!isSubmited) {
                      this.vm.$storage.homework.setCacheItem({
                        id,
                        value: {
                          record,
                          questions,
                          questionIndex: 0
                        }
                      })
                    }
                  }

                  // 关闭加载动画
                  clearTimeout(timer)
                  loading.close()

                  if (!isSubmited) {
                    // 去提交
                    if (subjectId == '66') {
                      // 英语听说
                      this.vm.$router.push('/pages/homework/todo/question/english/index')
                    } else {
                      this.vm.$router.push('/pages/homework/todo/question/xkw/index')
                    }
                  } else {
                    // 查看详情
                    if (subjectId == '66') {
                      // 英语听说
                      this.vm.$router.push('/pages/homework/detail/question/english/index')
                    } else {
                      this.vm.$router.push('/pages/homework/detail/question/xkw/index')
                    }
                  }
                }

                // 弹窗提示
                if (!studentStatus && answerTime && answerTimeType === 2) {
                  this.vm.$popup.show({
                    type: 'confirm',
                    success: (popup) => {
                      popup.$on('cancel', () => {
                        this.vm.$popup.hide('confirm')
                      })
                      popup.$on('confirm', async () => {
                        this.vm.$popup.hide('confirm')
                        start()
                      })
                      popup.setData({
                        content: `当前已限制作答时长，进入作答${answerTime}分钟后，系统将自动提交，确认开始作答？`,
                        confirmText: '确认'
                      })
                    }
                  })
                } else {
                  start()
                }
              }
              break
          }
        }
      }
    }
  },
  computed: {
    ...mapState(['homework']),
    ...mapGetters(['studentId'])
  },
  mounted() {
    this.$store.dispatch('initHomeworkStorage')
    this.subjects.getList((subjectId) => {
      this.homeworks.loading = false
      this.homeworks.getList(subjectId)

      // 初始化模块使用记录
      this.$store.commit('setCurrentModuleUse', {
        vm: this._self,
        type: MODULE_ID.HOMEWORK,
        subjectId
      })
    })
  },
  methods: {
    ...mapActions(['getDictByType']),
    onPageBack() {
      // 缓存作业id
      this.saveStorageExamIds()
      // 发送最新的作业id给安卓
      if (window.android && this.lastHomeWorkId) {
        window.android.setLastHomeWorkId(this.lastHomeWorkId)
      }
      this.$router.back()
    },
    saveStorageExamIds() {
      // 缓存examIds
      const { examIds, storageExamIds } = this
      const newExamIds = {}

      for (let subjectId in examIds) {
        newExamIds[subjectId] = examIds[subjectId]
      }

      for (let subjectId in storageExamIds) {
        if (newExamIds[subjectId]) {
          const ids = newExamIds[subjectId]
          newExamIds[subjectId] = Array.from(new Set(storageExamIds[subjectId].concat(ids)))
        } else {
          newExamIds[subjectId] = storageExamIds[subjectId]
        }
      }

      for (let subjectId in newExamIds) {
        this.$storage.homework.getExamIdsItem(subjectId).then(({ success }) => {
          if (success) {
            this.$storage.homework.putExamIdsItem({
              subjectId,
              value: newExamIds[subjectId]
            })
          } else {
            this.$storage.homework.setExamIdsItem({
              subjectId,
              value: newExamIds[subjectId]
            })
          }
        })
      }
    }
  }
}
</script>

<style lang="scss" scoped></style>
